<?php
/**
 * @package DomDateTime
 * @author Oliver Leisalu
 */
class DomDateTime {
	
	private $stamp;
	
	private $defaultFormat = 'Y-m-d H:i:s';
	
	/**
	 * @param Mixed $stamp Unix timestamp or datetime accepted to strtotime. Default is now.
	 */
	public static function c( $stamp = 'now' ) {
		return new DomDateTime( $stamp );
	}
	/**
	 * @param Mixed $stamp Unix timestamp or datetime accepted to strtotime. Default is now.
	 */
	public function __construct( $stamp = 'now' ) {
		$this->set( $stamp );
	}
	/**
	 * @param Mixed $stamp Unix timestamp or datetime accepted to strtotime. Default is now.
	 */
	public function set( $stamp ) {
		
		if( $stamp == NULL) 
			$this->stamp = NULL;
		else
			$this->stamp = is_numeric($stamp) ? (int)$stamp : (int)strtotime($stamp);
	}
	
	public function setDefaultFormat( $format ) {
		$this->defaultFormat = $format;
	}
	
	public function isNull() {
		return $this->stamp === NULL;
	}
	
	/**
	 * @param String $format Anything accepted to function date
	 * @return String
	 */
	public function date( $format = NULL ) {
		if( $this->stamp === NULL )
			return NULL;
				
		if( $format === NULL )
			$format = $this->defaultFormat;
		
		return date($format, $this->stamp );
	}

	/**
	 * Make time from current datetime. If any input is NULL, then it is replaces with current datetime matching value.
	 * $datetime = new DomDateTime('2008-10-10 10:12:44');
	 * echo $datetime->mktime(NULL,NULL,NULL,0,0,0)->date(); // 2008-10-10 00:00:00
	 *
	 * @param Int $year
	 * @param Int $month
	 * @param Int $day
	 * @param Int $hour
	 * @param Int $minute
	 * @param Int $second
	 * @return DomDateTime
	 */
	public function mktime( $year = NULL, $month = NULL, $day = NULL, $hour = NULL, $minute = NULL, $second = NULL ) {
		if( $year === NULL ) $year = date('Y', $this->stamp);
		if( $month === NULL ) $month = date('m', $this->stamp);
		if( $day === NULL ) $day = date('d', $this->stamp);
		if( $hour === NULL ) $hour = date('H', $this->stamp);
		if( $minute === NULL ) $minute = date('i', $this->stamp);
		if( $second === NULL ) $second = date('s', $this->stamp);
		return new DomDateTime( mktime( $hour, $minute, $second, $month, $day, $year ) );
	}
	
	/**
	 * @return DomDateTime
	 */
	public function getMonthFirstDay() {
		return new DomDateTime( mktime(0,0,0, date('m', $this->stamp), 1, date('Y', $this->stamp) ) );
	}
	/**
	 * @return DomDateTime
	 */
	public function getMonthLastDay() {
		return new DomDateTime( mktime(23,59,59, date('m', $this->stamp), date('t', $this->stamp ), date('Y', $this->stamp) ) );
	}
	/**
	 * @return DomDateTimePeriod
	 */
	public function getMonthPeriod() {
		return new DomDateTimePeriod( $this->getMonthFirstDay(), $this->getMonthLastDay() );
	}

	/**
	 * Samples:
	 * 
	 * $dateTime->in('future);
	 * $dateTime->in('past');
	 * 
	 * $dateTime->in('-1 day'); // today or yesterday
	 * $dateTime->in('now'); // today
	 * $dateTime->in('+1 day'); // today or tomorrow
	 * 
	 * $dateTime->is('-4 days'); // is within 4 days before now
	 * $dateTime->is('+4 days'); // is within 4 days from now
	 * 
	 * @param String $var
	 * @param String $compareFormat Value acceptable to date function. Default is Ymd. Notice that format result must be numberic
	 * @return Bool
	 */
	public function in( $var, $compareFormat = 'Ymd' ) {
			
		$a = (int)date($compareFormat, $this->stamp);
		$c = (int)date($compareFormat);
		
		if( $var == 'future') {
			return $a > $c;
			
		} else if( $var == 'past') {
			return $a < $c;
		
		} else {
			
			$stamp = strtotime($var);
			$mark = substr($var,0,1);
		
			$b = (int)date($compareFormat, $stamp );
			
			if( $mark == '+' ) {
				return $a <= $b && $a >= $c;
			
			} else if( $mark == '-' ){
				return $a >= $b && $a <= $c;
			
			} else {
				throw new RuntimeException( 'is input in invalid format. Given input: "'.$var.'"');
			}
		}
	}
	
	/**
	 * Samples:
	 * $dateTime->is('today);
	 * $dateTime->is('tomorrow');
	 * $dateTime->is('yesterday);
	 * $dateTime->is('workday);
	 * 
	 * $dateTime->is('-1 day'); // same as yesterday
	 * $dateTime->is('now'); // same as today
	 * $dateTime->is('+1 day'); // same as tomorrow
	 * 
	 * @param String $var
	 * @param String $compareFormat Value acceptable to date function. Default is Ymd. Notice that format result must be numberic
	 * @return Bool
	 */
	public function is( $var, $compareFormat = 'Ymd' ) {
		
		if( $var == 'tomorrow') {
			$stamp = strtotime('+1 day');
		
		} else if( $var == 'today') {
			$stamp = strtotime('now');

		} else if( $var == 'yesterday') {
			$stamp = strtotime('-1 day');
		
		} else if( $var == 'workday') {
			return date('N', $this->stamp ) <= 5;
			
		} else {
			$stamp = strtotime($var);
		}
			
		$a = (int)date($compareFormat, $this->stamp);
		$b = (int)date($compareFormat, $stamp );
		
		return $a == $b;
	}
	
	/**
	 * Adds time to current stamp. Accepts anything accepted by strtotime
	 * If you add date (like 2009-10-10), difference is taken from now to that date and this difference is added.
	 *
	 * $date->add('+1 day');
	 * $date->add('+48 hours');
	 * 
	 * @param unknown_type $var
	 */
	public function add( $var ) {
		$this->stamp += strtotime($var) - strtotime('now');
	}
	
	/**
	 * @return String
	 */
	public function getMonthName() {
		$monthNames = array('Jaanuar','Veebruar','Märts','Aprill','Mai','Juuni','Juuli','August','September','Oktoober','November','Detsember');
		return $monthNames[$this->date('n')-1];
	}
	/**
	 * @return String
	 */
	public function getDayName() {
		$dayNames = array('Esmaspäev','Teisipäev','Kolmapäev','Neljapäev','Reede','Laupäev','Pühapäev');
		return $dayNames[$this->date('N')-1];
	}
	
	/**
	 * @return Int
	 */
	public function getStamp() {
		return $this->stamp;
	}
	
	/**
	 * @return String
	 */
	public function __toString() {
		return $this->date();
	}
	
}
?>